#include "domain.h"
#include "../hed/entity/face.h"
#include "../hed/entity/loop.h"
#include "../hed/entity/halfedge.h"
#include "../hed/entity/edge.h"
#include <math.h>
#include <string>
#include <sstream>
#include "../mesh/mesh2.h"
#include "../mesh/meshgenerator.h"



Domain::Domain( Face* _face )
: m_face( _face )
, m_attribute( NULL )
{
  Loop* loop = m_face->getFloops();
  Loop* loopOut = m_face->getLoopOut();
  do
  {
    if( loop == loopOut ) // testing first just to the external loop
    {
      HalfEdge* h = loop->getLedg();
      do
      {
        bool isInverted = true;
        if( h->getEdg()->getFirstVertex() == h->getVtx() )
          isInverted = false;
        Boundary* bound = new Boundary( h->getEdg(), isInverted );
        m_bounds.push_back( bound );
      }
      while( (h = h->getNxt()) != loop->getLedg() );
    }
  }
  while(( loop = loop->getNextl()) != NULL );

}

void 
Domain::getBoundaries( list<Boundary*>& bound )
{
  bound = m_bounds;
}


bool 
Domain::isSelected()
{
  return m_face->isSelected();
}


void 
Domain::cleanMesh()
{
  m_pts.clear();
  m_conn.clear();
}




void 
Domain::generateMesh(int _type,int step)
{
  m_pts.clear();
  m_conn.clear();

  clist *clistOp = NULL;
  // obtains the boundary points of each domain
  vector<IPoint> bound;
  list<Boundary*>::iterator itB;
  for( itB = m_bounds.begin(); itB != m_bounds.end(); itB++ )
  {
    vector<IPoint> bPt = (*itB)->getSubdivisionPoints();
    for( unsigned int i=1; i<bPt.size(); i++)
    {
      bound.push_back( bPt[i] );
    }
  }


  if (_type == 2) // Advancing Front
  {
    int np = (int) bound.size();
    for( int i = 0; i < np; ++i )
    {
      double cx   = bound[i].getX();
      double cy = bound[i].getY();
      No *pno=new No;
      pno->x = cx;
      pno->y = cy;
      pno->i=i;
      push_circ( &clistOp , pno);
    }
    vector<Triangulo*> listaTri;
    vector<No> listaNo;
    Mesh2 obj;
  obj.generateMesh(clistOp, listaTri , listaNo,step);

    for( int i = 0; i < listaNo.size(); ++i )
    {
      IPoint tmp( listaNo[i].x, listaNo[i].y, 0.0 );
      m_pts.push_back( tmp );
    }

    // get connectivity
    for( int i = 0; i < listaTri.size(); ++i )
    {
      vector<int> triang;
      triang.push_back( listaTri[i]->pto1->i );
      triang.push_back( listaTri[i]->pto2->i  );
      triang.push_back( listaTri[i]->pto3->i  );
      m_conn.push_back( triang );
    }
  }
  else
  {
    MeshGenerator mesher;
    mesher.generateMesh( bound, m_pts, m_conn );
  }


}


void 
Domain::getCenter( double& _xc, double& _yc )
{
  double z;
  m_face->getLoopOut()->getCenter(_xc,_yc,z);
}
